Add Address Sanitizer support to std::vector git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@208319 91177308-0d34-0410-b5e6-96231b3b80d8 
diff --git a/include/vector b/include/vector index 6ac78d5..2cc23e5 100644 --- a/include/vector +++ b/include/vector 
@@ -483,6 +483,7 @@  {  private:  typedef __vector_base<_Tp, _Allocator> __base; + typedef allocator<_Tp> __default_allocator_type;  public:  typedef vector __self;  typedef _Tp value_type; @@ -749,7 +750,9 @@  _LIBCPP_INLINE_VISIBILITY  void clear() _NOEXCEPT  { + size_type __old_size = size();  __base::clear(); + __annotate_shrink(__old_size);  __invalidate_all_iterators();  }   @@ -816,7 +819,9 @@  }  __get_db()->unlock();  #endif + size_type __old_size = size();  __base::__destruct_at_end(__new_last); + __annotate_shrink(__old_size);  }  template <class _Up>  void @@ -830,17 +835,52 @@  void  __emplace_back_slow_path(_Args&&... __args);  #endif + // The following functions are no-ops outside of AddressSanitizer mode. + // We call annotatations only for the default Allocator because other allocators + // may not meet the AddressSanitizer alignment constraints. + // See the documentation for __sanitizer_annotate_contiguous_container for more details. + void __annotate_contiguous_container + (const void *__beg, const void *__end, const void *__old_mid, const void *__new_mid) + { +#ifndef _LIBCPP_HAS_NO_ASAN + if (__beg && is_same<allocator_type, __default_allocator_type>::value) + __sanitizer_annotate_contiguous_container(__beg, __end, __old_mid, __new_mid); +#endif + } + + void __annotate_new(size_type __current_size) + { + __annotate_contiguous_container(data(), data() + capacity(), + data() + capacity(), data() + __current_size); + } + void __annotate_delete() + { + __annotate_contiguous_container(data(), data() + capacity(), + data() + size(), data() + capacity()); + } + void __annotate_increase(size_type __n) + { + __annotate_contiguous_container(data(), data() + capacity(), + data() + size(), data() + size() + __n); + } + void __annotate_shrink(size_type __old_size) + { + __annotate_contiguous_container(data(), data() + capacity(), + data() + __old_size, data() + size()); + }  };    template <class _Tp, class _Allocator>  void  vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v)  { + __annotate_delete();  __alloc_traits::__construct_backward(this->__alloc(), this->__begin_, this->__end_, __v.__begin_);  _VSTD::swap(this->__begin_, __v.__begin_);  _VSTD::swap(this->__end_, __v.__end_);  _VSTD::swap(this->__end_cap(), __v.__end_cap());  __v.__first_ = __v.__begin_; + __annotate_new(size());  __invalidate_all_iterators();  }   @@ -848,6 +888,7 @@  typename vector<_Tp, _Allocator>::pointer  vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v, pointer __p)  { + __annotate_delete();  pointer __r = __v.__begin_;  __alloc_traits::__construct_backward(this->__alloc(), this->__begin_, __p, __v.__begin_);  __alloc_traits::__construct_forward(this->__alloc(), __p, this->__end_, __v.__end_); @@ -855,6 +896,7 @@  _VSTD::swap(this->__end_, __v.__end_);  _VSTD::swap(this->__end_cap(), __v.__end_cap());  __v.__first_ = __v.__begin_; + __annotate_new(size());  __invalidate_all_iterators();  return __r;  } @@ -874,6 +916,7 @@  this->__throw_length_error();  this->__begin_ = this->__end_ = __alloc_traits::allocate(this->__alloc(), __n);  this->__end_cap() = this->__begin_ + __n; + __annotate_new(0);  }    template <class _Tp, class _Allocator> @@ -920,6 +963,7 @@  vector<_Tp, _Allocator>::__construct_at_end(size_type __n)  {  allocator_type& __a = this->__alloc(); + __annotate_increase(__n);  do  {  __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_)); @@ -940,6 +984,7 @@  vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x)  {  allocator_type& __a = this->__alloc(); + __annotate_increase(__n);  do  {  __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), __x); @@ -960,6 +1005,7 @@  allocator_type& __a = this->__alloc();  for (; __first != __last; ++__first)  { + __annotate_increase(1);  __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first);  ++this->__end_;  } @@ -972,6 +1018,7 @@  allocator_type& __a = this->__alloc();  for (; __first != __last; ++__first)  { + __annotate_increase(1);  __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_),  _VSTD::move(*__first));  ++this->__end_; @@ -1535,6 +1582,7 @@  {  if (this->__end_ != this->__end_cap())  { + __annotate_increase(1);  __alloc_traits::construct(this->__alloc(),  _VSTD::__to_raw_pointer(this->__end_), __x);  ++this->__end_; @@ -1552,6 +1600,7 @@  {  if (this->__end_ < this->__end_cap())  { + __annotate_increase(1);  __alloc_traits::construct(this->__alloc(),  _VSTD::__to_raw_pointer(this->__end_),  _VSTD::move(__x)); @@ -1584,6 +1633,7 @@  {  if (this->__end_ < this->__end_cap())  { + __annotate_increase(1);  __alloc_traits::construct(this->__alloc(),  _VSTD::__to_raw_pointer(this->__end_),  _VSTD::forward<_Args>(__args)...); @@ -1666,6 +1716,7 @@  pointer __p = this->__begin_ + (__position - begin());  if (this->__end_ < this->__end_cap())  { + __annotate_increase(1);  if (__p == this->__end_)  {  __alloc_traits::construct(this->__alloc(), @@ -1705,6 +1756,7 @@  pointer __p = this->__begin_ + (__position - begin());  if (this->__end_ < this->__end_cap())  { + __annotate_increase(1);  if (__p == this->__end_)  {  __alloc_traits::construct(this->__alloc(), @@ -1743,6 +1795,7 @@  pointer __p = this->__begin_ + (__position - begin());  if (this->__end_ < this->__end_cap())  { + __annotate_increase(1);  if (__p == this->__end_)  {  __alloc_traits::construct(this->__alloc(), @@ -1794,6 +1847,7 @@  }  if (__n > 0)  { + __annotate_increase(__n);  __move_range(__p, __old_last, __p + __old_n);  const_pointer __xr = pointer_traits<const_pointer>::pointer_to(__x);  if (__p <= __xr && __xr < this->__end_) @@ -1904,6 +1958,7 @@  }  if (__n > 0)  { + __annotate_increase(__n);  __move_range(__p, __old_last, __p + __old_n);  _VSTD::copy(__first, __m, __p);  }